#include <bits/stdc++.h>
using namespace std;

/*
  将“正交移动”看作“步数+1、魔法不变”，将“对角移动”看作“步数不变、魔法+1”。
  先用一次 0–1 BFS（deque）求出每个格子的最少“正交步数”（dist_steps），其中对角边权为 0，正交边权为 1。
  然后在仅包含 dist_steps <= D 的格子子图上，再做一次 0–1 BFS（deque）求出
  在保证“正交步数 = dist_steps”前提下的最少“魔法数”（dist_magic），其中跨层正交边权为 0，对角同层边权为 1。

  n,m ≤ 5000，总格子 ≤ 25e6。我们用 int16_t 数组存 dist_steps 和 dist_magic，
  占用约 2×25e6×2B ≈ 100MB，再加上 grid 约 25MB，峰值 ~130MB，足够通过。  
  时间方面两次 0–1 BFS 共访问约 25e6×常数次，C++ 下可在 2s 内完成。
*/

static const int MAXN = 5000;
static const int16_t INF16 = 30000;  // 远大于可能的最大距离或魔法数

int n, m;
vector<string> grid;

// 四个正交方向：上、下、左、右
int dx4[4]   = { -1, +1,  0,  0 };
int dy4[4]   = {  0,  0, -1, +1 };
// 四个对角方向：左上、右上、左下、右下
int dx_diag[4] = { -1, -1, +1, +1 };
int dy_diag[4] = { -1, +1, -1, +1 };

// 判断 (i,j) 是否在地图范围内
inline bool inBounds(int i, int j) {
    return (i >= 0 && i < n && j >= 0 && j < m);
}

static int16_t dist_steps[MAXN][MAXN];
static int16_t dist_magic[MAXN][MAXN];

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n >> m;
    grid.resize(n);
    for(int i = 0; i < n; i++){
        cin >> grid[i];
    }

    // 定位起点 X=(sx,sy) 和 终点 W=(tx,ty)
    int sx=-1, sy=-1, tx=-1, ty=-1;
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            if(grid[i][j] == 'X'){
                sx = i; sy = j;
                grid[i][j] = '.';
            }
            if(grid[i][j] == 'W'){
                tx = i; ty = j;
                grid[i][j] = '.';
            }
        }
    }

    // ——— 第一阶段：0–1 BFS 求 dist_steps[i][j]（对角权0、正交权1） ———
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            dist_steps[i][j] = INF16;
        }
    }
    deque<pair<int,int>> dq;
    dist_steps[sx][sy] = 0;
    dq.push_front({sx, sy});

    while(!dq.empty()){
        auto [x,y] = dq.front();
        dq.pop_front();
        int16_t cd = dist_steps[x][y];
        // 对角边：权 0 → push_front
        for(int k = 0; k < 4; k++){
            int nx = x + dx_diag[k];
            int ny = y + dy_diag[k];
            if(!inBounds(nx, ny)) continue;
            if(grid[nx][ny] == '#') continue;
            if(dist_steps[nx][ny] > cd){
                dist_steps[nx][ny] = cd;
                dq.push_front({nx, ny});
            }
        }
        // 正交边：权 1 → push_back
        for(int k = 0; k < 4; k++){
            int nx = x + dx4[k];
            int ny = y + dy4[k];
            if(!inBounds(nx, ny)) continue;
            if(grid[nx][ny] == '#') continue;
            if(dist_steps[nx][ny] > cd + 1){
                dist_steps[nx][ny] = cd + 1;
                dq.push_back({nx, ny});
            }
        }
    }

    int16_t D = dist_steps[tx][ty];
    if(D == INF16){
        cout << "-1 -1\n";
        return 0;
    }

    // ——— 第二阶段：仅在 dist_steps <= D 的子图上做 0–1 BFS 求 dist_magic ———
    for(int i = 0; i < n; i++){
        for(int j = 0; j < m; j++){
            dist_magic[i][j] = INF16;
        }
    }
    deque<pair<int,int>> dq2;
    dist_magic[sx][sy] = 0;
    dq2.push_front({sx, sy});

    while(!dq2.empty()){
        auto [x,y] = dq2.front();
        dq2.pop_front();
        int16_t cm = dist_magic[x][y];
        int16_t cd = dist_steps[x][y];
        if(x == tx && y == ty) break;

        // 同层对角：权 1 → push_back
        for(int k = 0; k < 4; k++){
            int nx = x + dx_diag[k];
            int ny = y + dy_diag[k];
            if(!inBounds(nx, ny)) continue;
            if(grid[nx][ny] == '#') continue;
            if(dist_steps[nx][ny] != cd) continue;
            int16_t nm = cm + 1;
            if(nm < dist_magic[nx][ny]){
                dist_magic[nx][ny] = nm;
                dq2.push_back({nx, ny});
            }
        }
        // 跨层正交：权 0 → push_front
        if(cd < D){
            for(int k = 0; k < 4; k++){
                int nx = x + dx4[k];
                int ny = y + dy4[k];
                if(!inBounds(nx, ny)) continue;
                if(grid[nx][ny] == '#') continue;
                if(dist_steps[nx][ny] != cd + 1) continue;
                int16_t nm = cm;
                if(nm < dist_magic[nx][ny]){
                    dist_magic[nx][ny] = nm;
                    dq2.push_front({nx, ny});
                }
            }
        }
    }

    int16_t ansMagic = dist_magic[tx][ty];
    if(ansMagic == INF16){
        cout << "-1 -1\n";
    } else {
        cout << D << " " << ansMagic << "\n";
    }
    return 0;
}